// ES6 引入 rest 参数（形式为...变量名），
// 用于获取函数的多余参数，这样就不需要使用arguments对象了。
// rest 参数搭配的变量是一个数组，该变量将多余的参数放入数组中。

function add(...values) {
    let sum = 0;

    for (let val of values) {
        sum += val;
    }

    return sum;
}

console.log(add(2, 5, 3))    // 10

// ES6 允许使用“箭头”（=>）定义函数。

let f1=v => v ;
// 等同于
let f2= function (vv) {
    return vv;
};

console.log(f1(88));
console.log(f2(99));

// 如果箭头函数不需要参数或需要多个参数，就使用一个圆括号代表参数部分.

let f3 = () => 5;
console.log(f3());
// 等同于

let f33 = function () { return 5 };
console.log(f33());

let sum = (num1, num2) => num1 + num2;

let sum2 =(n1,n2) => n1+n2;
console.log(sum2(1,7));

// 等同于
let sum3 = function(num01, num02) {
    return num01 + num02;
};


//如果箭头函数的代码块部分多于一条语句，就要使用大括号将它们括起来，并且使用return语句返回。

let sum6 = (num1, num2) => { return num1 + num2; }
console.log(sum6(9,5));

//由于大括号被解释为代码块，所以如果箭头函数直接返回一个对象，必须在对象外面加上括号，否则会报错。

let getTempItem = id => ({ id: id, name: "Temp" });
console.log(getTempItem(100));      //{ id: 100, name: 'Temp' }

//箭头函数可以与变量解构结合使用。
const fullA = ({ first, last }) => first + ' ' + last;

// 等同于
function fullB(person) {
    return person.first + ' ' + person.last;
}

// 使用注意点:
// 箭头函数有几个使用注意点。
// （1）函数体内的this对象，就是定义时所在的对象，而不是使用时所在的对象。
// （2）不可以当作构造函数，也就是说，不可以使用new命令，否则会抛出一个错误。
// （3）不可以使用arguments对象，该对象在函数体内不存在。如果要用，可以用 rest 参数代替。
// （4）不可以使用yield命令，因此箭头函数不能用作 Generator 函数。

// 上面四点中，第一点尤其值得注意。this对象的指向是可变的，但是在箭头函数中，它是固定的。

function food() {
    setTimeout(() => {
        console.log('id:', this.id);
    }, 100);
}
const id=90;
food.call({ id: 19 });   // id: 19



function Timer() {
    this.s1 = 0;
    this.s2 = 0;
    // 箭头函数: this绑定定义时所在的作用域（即Timer函数）
    setInterval(() => this.s1++, 1000);
    // 普通函数: this指向运行时所在的作用域（即全局对象）。
    setInterval(function () {
        this.s2++;
    }, 1000);
}

let timer = new Timer();

setTimeout(() => console.log('s1: ', timer.s1), 3100);   //3100 毫秒之后，timer.s1 被更新了 3 次,所以 s1:  3
setTimeout(() => console.log('s2: ', timer.s2), 3100);   //而timer.s2一次都没更新。所以 s2:  0

//箭头函数可以让this指向固定化，这种特性很有利于封装回调函数。
//箭头函数里面根本没有自己的this，而是引用外层的this。所以也就不能用作构造函数。
let handler = {
    id: '123456',

    init: function() {
        document.addEventListener('click',
            event => this.doSomething(event.type), false);
    },

    doSomething: function(type) {
        console.log('Handling ' + type  + ' for ' + this.id);
    }
};


